﻿using LCL.Caching;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting;

namespace LCL.IBuilder
{
    public class BuilderFactory
    {
        private static LCache cache = LCache.Instance;
        public List<BuilderDescriptor> GetBuilderAll()
        {
            string cacheKey = "BuilderFactory-GetBuilderAll";
            object obj = cache.Get<object>(cacheKey);
            if (obj == null)
            {
                #region MyRegion
                var builderTypes = new List<BuilderDescriptor>();
                var dirPath = AppDomain.CurrentDomain.BaseDirectory;
                var builderFolder = new DirectoryInfo(dirPath);
                var binFiles = builderFolder.GetFiles("LCL.*.dll", SearchOption.AllDirectories);
                foreach (var item in binFiles)
                {
                    var assembly = Assembly.Load(AssemblyName.GetAssemblyName(item.FullName));
                    foreach (var t in assembly.GetTypes())
                    {
                        if (typeof(IProjectBuilder).IsAssignableFrom(t))
                        {
                            if (!t.IsInterface)
                            {
                                if (t.IsClass && !t.IsAbstract)
                                {
                                    var handle = assembly.CreateInstance(t.FullName);
                                    IProjectBuilder objType = handle as IProjectBuilder;
                                    builderTypes.Add(new BuilderDescriptor
                                    {
                                        BuilderType = t,
                                        BuilderAssembly = assembly,
                                        Name = objType.Name
                                    });
                                }
                            }
                        }
                    }
                }
                cache.Set(cacheKey, builderTypes);
                return builderTypes;
                #endregion
            }
            return (List<BuilderDescriptor>)obj;
        }
    }

    [DebuggerDisplay("{Name} {BuilderType.FullName} ")]
    public class BuilderDescriptor
    {
        public string Name { get; set; }
        public Assembly BuilderAssembly { get; set; }
        public Type BuilderType { get; set; }
        public IProjectBuilder ProjectBuilder
        {
            get
            {
                var handle = BuilderAssembly.CreateInstance(BuilderType.FullName);
                IProjectBuilder objType = handle as IProjectBuilder;
                return objType;
            }
        }
    }
}
